# app/core/workflow_engine.py
import logging
from typing import Dict, Any, Union
from .nlp_processor import NLPParser, ParsedQuery
from .sql_generator import SQLGenerator
from app.database.mysql_connector import MySQLConnector
from app.database.neo4j_connector import Neo4jConnector
from app.services.deepseek import DeepSeekClient
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()


# 设置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger("nlp_processor")

class WorkflowEngine:
    def __init__(self, user_id: str):
        """
        初始化工作流引擎
        :param user_id: 当前用户ID
        """
        self.user_id = user_id
        self.nlp_parser = NLPParser()
        self.sql_generator = SQLGenerator(user_id)
        self.mysql_connector = MySQLConnector()
        self.neo4j_connector = Neo4jConnector()
        self.deepseek_client = DeepSeekClient()

        logger.info(f"工作流引擎初始化完成 (用户ID: {user_id})")

    def process_query(self, user_query: str) -> Dict[str, Any]:
        """
        处理用户查询的全流程
        :param user_query: 用户输入的自然语言查询
        :return: 包含响应和可视化数据的字典
        """
        logger.info(f"处理用户查询: '{user_query}'")

        try:
            # 1. NLP解析
            parsed_query = self.nlp_parser.parse_query(user_query)
            logger.info(f"NLP解析结果: 意图={parsed_query.intent}, 实体={parsed_query.entities}")

            # 2. 根据意图执行不同工作流
            if parsed_query.intent == "add_expense":
                return self._process_add_expense(parsed_query.entities)
            elif parsed_query.intent == "query_expense":
                return self._process_query_expense(parsed_query.entities)
            elif parsed_query.intent == "generate_report":
                return self._process_generate_report(parsed_query.entities)
            elif parsed_query.intent == "financial_advice":
                return self._process_financial_advice(parsed_query.entities)
            else:
                return self._fallback_response(parsed_query)

        except Exception as e:
            logger.exception(f"处理查询时出错: {str(e)}")
            return {
                "response": "抱歉，处理您的请求时出错了，请稍后再试。",
                "visualization": None
            }

    def _process_add_expense(self, entities: Dict[str, Any]) -> Dict[str, Any]:
        """
        处理添加交易工作流
        """
        # 生成SQL并执行
        logger.info(f"生成SQL并执行: {entities}")

        sql = self.sql_generator.generate_sql("add_expense", entities)
        logger.info(f"添加交易SQL: {sql}")

        try:
            # 执行SQL
            self.mysql_connector.execute(sql)

            # 构建响应
            money = entities.get("money", 0)
            category = entities.get("category", "支出")
            merchant = entities.get("merchant", "")

            if merchant:
                response = f"已成功记录您在{merchant}的{money}元{category}！"
            else:
                response = f"已成功记录您的{money}元{category}！"

            return {"response": response, "visualization": None}

        except Exception as e:
            logger.error(f"添加交易失败: {str(e)}")
            return {"response": "抱歉，记录交易时出错了。", "visualization": None}

    def _process_query_expense(self, entities: Dict[str, Any]) -> Dict[str, Any]:
        """
        处理查询交易工作流
        """
        # 生成SQL并执行
        logger.info(f"查询交易SQL=============:{entities}")
        sql = self.sql_generator.generate_sql("query_expense", entities)
        logger.info(f"查询交易SQL: {sql}")

        try:
            # 执行SQL
            results = self.mysql_connector.query(sql)

            if not results:
                return {"response": "没有找到符合条件的交易记录。", "visualization": None}
            logger.info(f"执行SQL=======: {results}")

            # 构建响应
            if len(results) == 1:
                transaction = results[0]
                response = f"找到一条记录：{transaction['transaction_date']} 在 {transaction['merchant']} 消费 {transaction['money']}元 ({transaction['category']})"
            else:
                total = sum(float(t['money']) for t in results)
                response = f"找到{len(results)}条记录，总计{total}元。"

            # 简单可视化
            visualization = self._create_simple_visualization(results)

            return {"response": response, "visualization": visualization}

        except Exception as e:
            logger.error(f"查询交易失败: {str(e)}")
            return {"response": "抱歉，查询交易时出错了。", "visualization": None}

    def _process_generate_report(self, entities: Dict[str, Any]) -> Dict[str, Any]:
        """
        处理生成报告工作流
        """
        # 生成SQL并执行
        sql = self.sql_generator.generate_sql("generate_report", entities)
        logger.debug(f"生成报告SQL: {sql}")

        try:
            # 执行SQL
            report_data = self.mysql_connector.query(sql)

            if not report_data:
                return {"response": "没有找到符合条件的报表数据。", "visualization": None}

            # 根据报告类型构建响应
            report_type = entities.get("report_type", "summary")

            if report_type == "category_summary":
                response = "以下是根据类别的消费统计："
                visualization = self._create_category_visualization(report_data)
            elif report_type == "trend":
                response = "以下是消费趋势统计："
                visualization = self._create_trend_visualization(report_data)
            else:
                total_income = report_data[0].get("total_income", 0)
                total_expense = report_data[0].get("total_expense", 0)
                response = f"财务摘要：收入{total_income}元，支出{total_expense}元"
                visualization = None

            return {"response": response, "visualization": visualization}

        except Exception as e:
            logger.error(f"生成报告失败: {str(e)}")
            return {"response": "抱歉，生成报告时出错了。", "visualization": None}

    def _process_financial_advice(self, entities: Dict[str, Any]) -> Dict[str, Any]:
        """
        处理财务建议工作流
        """
        # 1. 获取历史数据
        sql = self.sql_generator.generate_sql("financial_advice", entities)
        logger.debug(f"财务建议SQL: {sql}")

        try:
            # 执行SQL获取历史数据
            history_data = self.mysql_connector.query(sql)

            if not history_data:
                return {"response": "您还没有足够的交易记录来提供建议。", "visualization": None}

            # 2. 查询知识图谱获取相关概念
            category = entities.get("category", "")
            if category:
                knowledge = self.neo4j_connector.query_related_concepts(category)
            else:
                knowledge = []

            # 3. 构建提示词
            prompt = self._build_advice_prompt(history_data, knowledge, entities)

            # 4. 调用DeepSeek生成建议
            advice = self.deepseek_client.generate_advice(prompt)

            # 5. 创建可视化
            visualization = self._create_category_visualization(
                self._summarize_by_category(history_data)
            )

            return {"response": advice, "visualization": visualization}

        except Exception as e:
            logger.error(f"生成财务建议失败: {str(e)}")
            return {"response": "抱歉，生成财务建议时出错了。", "visualization": None}

    def _fallback_response(self, parsed_query: ParsedQuery) -> Dict[str, Any]:
        """
        处理未知意图的响应
        """
        logger.warning(f"未知意图: {parsed_query.intent}")
        return {
            "response": "抱歉，我还没学会处理这类请求。您可以尝试查询支出、生成报告或添加交易记录。",
            "visualization": None
        }

    def _create_simple_visualization(self, transactions: list) -> dict:
        """
        创建简单的交易可视化
        """
        # 这里简化实现，实际应使用ECharts等库
        categories = {}
        for t in transactions:
            cat = t['category']
            categories[cat] = categories.get(cat, 0) + float(t['money'])

        return {
            "type": "pie",
            "title": "消费类别分布",
            "data": [{"name": k, "value": v} for k, v in categories.items()]
        }

    def _create_category_visualization(self, data: list) -> dict:
        """
        创建分类统计可视化
        """
        return {
            "type": "bar",
            "title": "消费类别统计",
            "xAxis": {"data": [d['category'] for d in data]},
            "series": [{
                "name": "金额",
                "type": "bar",
                "data": [d['total_amount'] for d in data]
            }]
        }

    def _create_trend_visualization(self, data: list) -> dict:
        """
        创建趋势可视化
        """
        return {
            "type": "line",
            "title": "消费趋势",
            "xAxis": {"data": [d['month'] for d in data]},
            "series": [{
                "name": "支出",
                "type": "line",
                "data": [d['total_expense'] for d in data]
            }]
        }

    def _build_advice_prompt(self, history: list, knowledge: list, entities: dict) -> str:
        """
        构建财务建议提示词
        """
        # 1. 用户历史数据摘要
        history_summary = "\n".join(
            f"{t['transaction_date']} - {t['category']}: {t['money']}元"
            for t in history[:10]  # 最多显示10条
        )

        # 2. 相关知识
        knowledge_summary = "\n".join(
            f"{k['name']}: {k['description'][:100]}..."
            for k in knowledge[:3]  # 最多显示3条
        )

        # 3. 用户具体需求
        user_need = entities.get("note", "一般预算建议")

        # 4. 构建完整提示
        return f"""
        你是一个专业的财务顾问，请根据以下信息为用户提供建议：

        ### 用户近期消费记录（最多10条）：
        {history_summary}

        ### 相关知识：
        {knowledge_summary}

        ### 用户具体需求：
        {user_need}

        请用友好的语气提供3-5条具体建议，每条建议不超过50字。
        """

    def _summarize_by_category(self, transactions: list) -> list:
        """
        按类别汇总交易数据
        """
        summary = {}
        for t in transactions:
            cat = t['category']
            summary[cat] = summary.get(cat, 0) + t['money']

        return [
            {"category": k, "total_amount": v}
            for k, v in summary.items()
        ]


# 使用示例
if __name__ == "__main__":
    engine = WorkflowEngine(user_id='cai')

    # 测试添加交易
    print("测试添加交易:")
    result = engine.process_query("昨天午餐在星巴克花了35元")
    print("响应:", result["response"])

    # 测试查询交易
    # print("\n测试查询交易:")
    # result = engine.process_query("本月餐饮支出多少")
    # print("响应:", result["response"])

    # # 测试生成报告
    # print("\n测试生成报告:")
    # result = engine.process_query("给我生成上个月的消费报告")
    # print("响应:", result["response"])
    #
    # # 测试财务建议
    # print("\n测试财务建议:")
    # result = engine.process_query("我应该如何规划我的餐饮预算？")
    # print("响应:", result["response"])